//
// GPSMapEdit
// (c) Konstantin Galichsky (kg@geopainting.com), 2007
// (c) Nikita Karnauhov (jinx@ac-sw.com), 2007
//
// Clean up external nodes.
//

# include "StdAfx.h"
# include "CleanUpExternalNodes.h"
# include "UndoRedo.h"
# include "MapView.h"

class CCleanUpExternalNodesAction : public CEditAction {
  public:
	CCleanUpExternalNodesAction (map_t & _map, size_t _cMinNodeCount) :
		m_map (_map),
		m_cMinNodeCount (_cMinNodeCount)
	{}

	virtual void GetName (string_t & _str) const {_str.append ("clean up external nodes");}
	virtual cu_t CanUndo () const {return cuYes;}
	virtual void Undo ();
	virtual void Redo ();

	virtual bool Do ();

  private:
	map_t & m_map;
	size_t m_cMinNodeCount;

	typedef std::list<rgnode_t *> nodesCleared_t;
	nodesCleared_t m_nodesCleared;
};

bool CCleanUpExternalNodesAction::Do () {
	CCritSec::CLock lock (g_cs);

	// Ensure that node counters are correct.
	m_map.CountRGNodes (true);

	for (rgnodes_t::iterator iNode = m_map.rgnodes.begin (); iNode != m_map.rgnodes.end (); ++ iNode) {
		rgnode_t & node = * iNode;
		if (! node.IsUsed ())
			continue;

		if (node.bIsExternal && node.btPolylines > m_cMinNodeCount) {
			node.bIsExternal = false;

			m_nodesCleared.push_back (& node);
		}
	}

	Refresh ();

	return true;
}

void CCleanUpExternalNodesAction::Undo () {
	CCritSec::CLock lock (g_cs);

	for (nodesCleared_t::iterator i = m_nodesCleared.begin (); i != m_nodesCleared.end (); ++ i) {
		rgnode_t * const pNode = * i;
		pNode->bIsExternal = true;
	}
}

void CCleanUpExternalNodesAction::Redo () {
	CCritSec::CLock lock (g_cs);

	for (nodesCleared_t::iterator i = m_nodesCleared.begin (); i != m_nodesCleared.end (); ++ i) {
		rgnode_t * const pNode = * i;
		pNode->bIsExternal = false;
	}
}

/////////////////////////////////////////

void ClearExternalNodes () {
	PerformEditAction (new CCleanUpExternalNodesAction (g_map, 0));
}

void CleanUpExternalNodes () {
	PerformEditAction (new CCleanUpExternalNodesAction (g_map, 1));
}

